package com.ruoyi.common.utils.http;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.URLConnection;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.activation.MimetypesFileTypeMap;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ruoyi.common.utils.StringUtils;

/**
 * 通用http发送方法
 * 
 * @author ruoyi
 */
public class HttpUtils
{
    private static final Logger log = LoggerFactory.getLogger(HttpUtils.class);

    /**
     * 向指定 URL 发送GET方法的请求
     *
     * @param url 发送请求的 URL
     * @param param 请求参数，请求参数应该是 name1=value1&name2=value2 的形式。
     * @return 所代表远程资源的响应结果
     */
    public static String sendGet(String url, String param)
    {
        StringBuilder result = new StringBuilder();
        BufferedReader in = null;
        try
        {
        	
            String urlNameString = url + "?" + param;
            log.info("sendGet - {}", urlNameString);
            URL realUrl = new URL(urlNameString);
            URLConnection connection = realUrl.openConnection();
            connection.setRequestProperty("accept", "*/*");
            connection.setRequestProperty("connection", "Keep-Alive");
            connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            connection.setRequestProperty("User-agent","Mozilla/4.0");
            connection.connect();
            in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            String line;
            while ((line = in.readLine()) != null)
            {
                result.append(line);
            }
            log.info("recv - {}", result);
        }
        catch (ConnectException e)
        {
            log.error("调用HttpUtils.sendGet ConnectException, url=" + url + ",param=" + param, e);
        }
        catch (SocketTimeoutException e)
        {
            log.error("调用HttpUtils.sendGet SocketTimeoutException, url=" + url + ",param=" + param, e);
        }
        catch (IOException e)
        {
            log.error("调用HttpUtils.sendGet IOException, url=" + url + ",param=" + param, e);
        }
        catch (Exception e)
        {
            log.error("调用HttpsUtil.sendGet Exception, url=" + url + ",param=" + param, e);
        }
        finally
        {
            try
            {
                if (in != null)
                {
                    in.close();
                }
            }
            catch (Exception ex)
            {
                log.error("调用in.close Exception, url=" + url + ",param=" + param, ex);
            }
        }
        return result.toString();
    }
    
    
    /**
     * 向指定 URL 发送GET方法的请求
     *
     * @param url 发送请求的 URL
     * @param param 请求参数，请求参数应该是 name1=value1&name2=value2 的形式。
     * @param head 请求参数，请求参数应该是 param1=value1, param2=value2 的形式。
     * @return 所代表远程资源的响应结果
     */
    public static String sendGet(String url, String param,String head)
    {
        StringBuilder result = new StringBuilder();
        BufferedReader in = null;
        try
        {
        	
            String urlNameString = url + "?" + param;
            log.info("sendGet - {}", urlNameString);
            URL realUrl = new URL(urlNameString);
            URLConnection connection = realUrl.openConnection();
            connection.setRequestProperty("accept", "*/*");
            connection.setRequestProperty("connection", "Keep-Alive");
            connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            connection.setRequestProperty("User-agent","Mozilla/4.0");
          //设置头部参数
            if (StringUtils.isNotEmpty(head)) {
				String[] headArray = head.split(",");
				for (String headString : headArray) {
					String[] split = headString.split("=");
					connection.setRequestProperty(split[0], split[1]);
				}
			}
            connection.connect();
            in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            String line;
            while ((line = in.readLine()) != null)
            {
                result.append(line);
            }
            log.info("recv - {}", result);
        }
        catch (ConnectException e)
        {
            log.error("调用HttpUtils.sendGet ConnectException, url=" + url + ",param=" + param, e);
        }
        catch (SocketTimeoutException e)
        {
            log.error("调用HttpUtils.sendGet SocketTimeoutException, url=" + url + ",param=" + param, e);
        }
        catch (IOException e)
        {
            log.error("调用HttpUtils.sendGet IOException, url=" + url + ",param=" + param, e);
        }
        catch (Exception e)
        {
            log.error("调用HttpsUtil.sendGet Exception, url=" + url + ",param=" + param, e);
        }
        finally
        {
            try
            {
                if (in != null)
                {
                    in.close();
                }
            }
            catch (Exception ex)
            {
                log.error("调用in.close Exception, url=" + url + ",param=" + param, ex);
            }
        }
        return result.toString();
    }

    
    
    
    /**
     * 向指定 URL 发送POST方法的请求
     *
     * @param url 发送请求的 URL
     * @param param 请求参数，请求参数应该是 name1=value1&name2=value2 的形式。
     * @return 所代表远程资源的响应结果
     */
    public static String sendPost(String url, String param)
    {
        PrintWriter out = null;
        BufferedReader in = null;
        StringBuilder result = new StringBuilder();
        try
        {
            String urlNameString = url + "?" + param;
            log.info("sendPost - {}", urlNameString);
            URL realUrl = new URL(urlNameString);
            URLConnection conn = realUrl.openConnection();
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            conn.setRequestProperty("Accept-Charset", "utf-8");
            conn.setRequestProperty("contentType", "utf-8");
            conn.setDoOutput(true);
            conn.setDoInput(true);
            out = new PrintWriter(conn.getOutputStream());
            out.print(param);
            out.flush();
            in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
            String line;
            while ((line = in.readLine()) != null)
            {
                result.append(line);
            }
            log.info("recv - {}", result);
        }
        catch (ConnectException e)
        {
            log.error("调用HttpUtils.sendPost ConnectException, url=" + url + ",param=" + param, e);
        }
        catch (SocketTimeoutException e)
        {
            log.error("调用HttpUtils.sendPost SocketTimeoutException, url=" + url + ",param=" + param, e);
        }
        catch (IOException e)
        {
            log.error("调用HttpUtils.sendPost IOException, url=" + url + ",param=" + param, e);
        }
        catch (Exception e)
        {
            log.error("调用HttpsUtil.sendPost Exception, url=" + url + ",param=" + param, e);
        }
        finally
        {
            try
            {
                if (out != null)
                {
                    out.close();
                }
                if (in != null)
                {
                    in.close();
                }
            }
            catch (IOException ex)
            {
                log.error("调用in.close Exception, url=" + url + ",param=" + param, ex);
            }
        }
        return result.toString();
    }

    /**
     * 向指定 URL 发送POST方法的请求
     *
     * @param url 发送请求的 URL
     * @param param 请求参数，请求参数应该是 name1=value1&name2=value2 的形式。
     * @param head 头部请求参数，请求参数应该是 param1=value1, param2=value2的形式。
     * @return 所代表远程资源的响应结果
     */
    public static String sendPost(String url, String param,String head)
    {
    	PrintWriter out = null;
    	//OutputStreamWriter out = null; //防止中文乱码
        BufferedReader in = null;
        StringBuilder result = new StringBuilder();
        try
        {
            String urlNameString = url + "?" + param;
            log.info("sendPost - {}", urlNameString);
            URL realUrl = new URL(urlNameString);
            // 打开和URL之间的连接
            URLConnection conn = realUrl.openConnection();
            // 设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            conn.setRequestProperty("Accept-Charset", "utf-8");
            conn.setRequestProperty("contentType", "utf-8");
            //设置头部参数
            if (StringUtils.isNotEmpty(head)) {
				String[] headArray = head.split(",");
				for (String headString : headArray) {
					String[] split = headString.split("=");
				 conn.setRequestProperty(split[0], split[1]);
				}
			}
            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // 获取URLConnection对象对应的输出流
           out = new PrintWriter(conn.getOutputStream());
           //out = new OutputStreamWriter(conn.getOutputStream(), "utf-8"); // 防止中文乱码  报400 8859_1
            // 发送请求参数
          //  out.print(param);
            // flush输出流的缓冲
            out.flush();
            // 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
            String line;
            while ((line = in.readLine()) != null)
            {
                result.append(line);
            }
            log.info("recv - {}", result);
        }
        catch (ConnectException e)
        {
            log.error("调用HttpUtils.sendPost ConnectException, url=" + url + ",param=" + param, e);
        }
        catch (SocketTimeoutException e)
        {
            log.error("调用HttpUtils.sendPost SocketTimeoutException, url=" + url + ",param=" + param, e);
        }
        catch (IOException e)
        {
            log.error("调用HttpUtils.sendPost IOException, url=" + url + ",param=" + param, e);
        }
        catch (Exception e)
        {
            log.error("调用HttpsUtil.sendPost Exception, url=" + url + ",param=" + param, e);
        }
        finally
        {
        	//使用finally块来关闭输出流、输入流
            try
            {
                if (out != null)
                {
                    out.close();
                }
                if (in != null)
                {
                    in.close();
                }
            }
            catch (IOException ex)
            {
                log.error("调用in.close Exception, url=" + url + ",param=" + param, ex);
            }
        }
        return result.toString();
    }

    
    
    
    
    public static String sendSSLPost(String url, String param)
    {
        StringBuilder result = new StringBuilder();
        String urlNameString = url + "?" + param;
        try
        {
            log.info("sendSSLPost - {}", urlNameString);
            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, new TrustManager[] { new TrustAnyTrustManager() }, new java.security.SecureRandom());
            URL console = new URL(urlNameString);
            HttpsURLConnection conn = (HttpsURLConnection) console.openConnection();
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            conn.setRequestProperty("Accept-Charset", "utf-8");
            conn.setRequestProperty("contentType", "utf-8");
            conn.setDoOutput(true);
            conn.setDoInput(true);

            conn.setSSLSocketFactory(sc.getSocketFactory());
            conn.setHostnameVerifier(new TrustAnyHostnameVerifier());
            conn.connect();
            InputStream is = conn.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            String ret = "";
            while ((ret = br.readLine()) != null)
            {
                if (ret != null && !ret.trim().equals(""))
                {
                    result.append(new String(ret.getBytes("ISO-8859-1"), "utf-8"));
                }
            }
            log.info("recv - {}", result);
            conn.disconnect();
            br.close();
        }
        catch (ConnectException e)
        {
            log.error("调用HttpUtils.sendSSLPost ConnectException, url=" + url + ",param=" + param, e);
        }
        catch (SocketTimeoutException e)
        {
            log.error("调用HttpUtils.sendSSLPost SocketTimeoutException, url=" + url + ",param=" + param, e);
        }
        catch (IOException e)
        {
            log.error("调用HttpUtils.sendSSLPost IOException, url=" + url + ",param=" + param, e);
        }
        catch (Exception e)
        {
            log.error("调用HttpsUtil.sendSSLPost Exception, url=" + url + ",param=" + param, e);
        }
        return result.toString();
    }

    private static class TrustAnyTrustManager implements X509TrustManager
    {
        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType)
        {
        }

        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType)
        {
        }

        @Override
        public X509Certificate[] getAcceptedIssuers()
        {
            return new X509Certificate[] {};
        }
    }

    private static class TrustAnyHostnameVerifier implements HostnameVerifier
    {
        @Override
        public boolean verify(String hostname, SSLSession session)
        {
            return true;
        }
    }
    
    
    /**
     * 向指定 URL 发送POST方法的请求
     *
     * @param url 发送请求的 URL
     * @param param 请求参数，请求参数应该是 name1=value1&name2=value2 的形式。
     * @param head 头部请求参数，请求参数应该是 param1=value1, param2=value2的形式。
     * @return 所代表远程资源的响应结果
     */
    public static String uploadForm(String url,String filePath, String param,String head){
    	  String filepath="E:\\ziliao\\0.jpg"; 
    	 /* String urlStr = "http://127.0.0.1:8080/minicms/up/up_result.jsp"; */
    	  Map<String, String> textMap = new HashMap<String, String>(); 
    	  textMap.put("name", "testname"); 
    	  Map<String, String> fileMap = new HashMap<String, String>(); 
    	  fileMap.put("userfile", filepath); 
    	  String ret = formUpload(url, textMap, fileMap); 
    	  System.out.println(ret); 
    	return null;
    }
    
    /** 
     * 上传图片 
     * 
     * @param urlStr 
     * @param textMap 
     * @param fileMap 
     * @return 
     */
    public static String formUpload(String urlStr, Map<String, String> textMap,
      Map<String, String> fileMap) { 
     String res = ""; 
     HttpURLConnection conn = null; 
     String BOUNDARY = "---------------------------123821742118716"; //boundary就是request头和上传文件内容的分隔符 
     try { 
      URL url = new URL(urlStr); 
      conn = (HttpURLConnection) url.openConnection(); 
      conn.setConnectTimeout(5000); 
      conn.setReadTimeout(30000); 
      conn.setDoOutput(true); 
      conn.setDoInput(true); 
      conn.setUseCaches(false); 
      conn.setRequestMethod("POST"); 
      conn.setRequestProperty("Connection", "Keep-Alive"); 
      conn 
        .setRequestProperty("User-Agent", 
          "Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.6)"); 
      conn.setRequestProperty("Content-Type", 
        "multipart/form-data; boundary=" + BOUNDARY); 
      OutputStream out = new DataOutputStream(conn.getOutputStream()); 
      // text 
      if (textMap != null) { 
       StringBuffer strBuf = new StringBuffer(); 
       Iterator iter = textMap.entrySet().iterator(); 
       while (iter.hasNext()) { 
        Map.Entry entry = (Map.Entry) iter.next(); 
        String inputName = (String) entry.getKey(); 
        String inputValue = (String) entry.getValue(); 
        if (inputValue == null) { 
         continue; 
        } 
        strBuf.append("\r\n").append("--").append(BOUNDARY).append( 
          "\r\n"); 
        strBuf.append("Content-Disposition: form-data; name=\""
          + inputName + "\"\r\n\r\n"); 
        strBuf.append(inputValue); 
       } 
       out.write(strBuf.toString().getBytes()); 
      } 
      // file 
      if (fileMap != null) { 
       Iterator iter = fileMap.entrySet().iterator(); 
       while (iter.hasNext()) { 
        Map.Entry entry = (Map.Entry) iter.next(); 
        String inputName = (String) entry.getKey(); 
        String inputValue = (String) entry.getValue(); 
        if (inputValue == null) { 
         continue; 
        } 
        File file = new File(inputValue); 
        String filename = file.getName(); 
        String contentType = new MimetypesFileTypeMap() 
          .getContentType(file); 
        if (filename.endsWith(".png")) { 
         contentType = "image/png"; 
        } 
        if (contentType == null || contentType.equals("")) { 
         contentType = "application/octet-stream"; 
        } 
        StringBuffer strBuf = new StringBuffer(); 
        strBuf.append("\r\n").append("--").append(BOUNDARY).append( 
          "\r\n"); 
        strBuf.append("Content-Disposition: form-data; name=\""
          + inputName + "\"; filename=\"" + filename 
          + "\"\r\n"); 
        strBuf.append("Content-Type:" + contentType + "\r\n\r\n"); 
        out.write(strBuf.toString().getBytes()); 
        DataInputStream in = new DataInputStream( 
          new FileInputStream(file)); 
        int bytes = 0; 
        byte[] bufferOut = new byte[1024]; 
        while ((bytes = in.read(bufferOut)) != -1) { 
         out.write(bufferOut, 0, bytes); 
        } 
        in.close(); 
       } 
      } 
      byte[] endData = ("\r\n--" + BOUNDARY + "--\r\n").getBytes(); 
      out.write(endData); 
      out.flush(); 
      out.close(); 
      // 读取返回数据 
      StringBuffer strBuf = new StringBuffer(); 
      BufferedReader reader = new BufferedReader(new InputStreamReader( 
        conn.getInputStream())); 
      String line = null; 
      while ((line = reader.readLine()) != null) { 
       strBuf.append(line).append("\n"); 
      } 
      res = strBuf.toString(); 
      reader.close(); 
      reader = null; 
     } catch (Exception e) { 
      System.out.println("发送POST请求出错。" + urlStr); 
      e.printStackTrace(); 
     } finally { 
      if (conn != null) { 
       conn.disconnect(); 
       conn = null; 
      } 
     } 
     return res; 
    } 
   }
    
